const test_StatementIf_1 = () => {
    //只有if
    const code = `if (1) {
        var c = 99
    }`
    log("code", code)
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 1, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "c", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},
    ]
    const result = parser(tokenList, 0)

    const expect = [{
        type: AstType.StatementIf,
        // if块运行的条件, 可以是表达式等
        condition: {
            type: TokenType.number,
            value: 1
        },
        // if的condition为true时，执行的作用域
        consequent: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable:{
                        type: TokenType.variable,
                        value:"c",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        },
        alternate: {
        }
    }]
    ensure(equals(result, expect), '### test_StatementIf_1')
}

const test_StatementIf_2 = () => {
    //if else
    const code = `if (1) {
        var c = 99
    } else {
        var a = 100
    }`
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 1, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "c", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "a", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 100, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},

    ]
    const result = parser(tokenList, 0)

    const expect = [{
        type:  AstType.StatementIf,
        // if块运行的条件, 可以是表达式等
        condition: {
            type: TokenType.number,
            value: 1
        },
        // if的condition为true时，执行的作用域
        consequent: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable: {
                        type: TokenType.variable,
                        value:"c",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        },
        // else的作用域
        alternate: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable:{
                        type: TokenType.variable,
                        value:"a",
                    },
                    value: {
                        type: TokenType.number,
                        value: 100,
                    }
                },
            ]
        }
    }]
    ensure(equals(result, expect), '### test_StatementIf_2')
}

const test_StatementIf_3 = () => {
    //if ifelse  else
    const code = ` if (1) {
        var a = 99
    } else if (2) {
        var b = 100
    } else {
        var c = 199
    }`
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 1, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "a", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 2, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "b", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 100, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "c", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 199, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},

    ]
    const result = parser(tokenList, 0)

    const expect =  [{
        type:  AstType.StatementIf,
        // if块运行的条件, 可以是表达式等
        condition: {
            type: TokenType.number,
            value: 1
        },
        // if的condition为true时，执行的作用域
        consequent: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable: {
                        type: TokenType.variable,
                        value:"a",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        },
        // else的作用域
        alternate: {
            type: AstType.StatementIf,
            condition: {
                type: TokenType.number,
                value: 2
            },
            consequent: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.DeclarationVariable,
                        kind: 'var',
                        variable: {
                            type: TokenType.variable,
                            value:"b",
                        },
                        value: {
                            type: TokenType.number,
                            value: 100,
                        }
                    },
                ]
            },
            alternate: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.DeclarationVariable,
                        kind: 'var',
                        variable: {
                            type: TokenType.variable,
                            value:"c",
                        },
                        value: {
                            type: TokenType.number,
                            value: 199,
                        }
                    },
                ]

            }
        }
    }]
    ensure(equals(result, expect), '### test_StatementIf_3')
}
const test_StatementIf_4 = () => {
    //if else if else if  else
    const code = ` if (1) {
        var a = 99
    } else if (2) {
        var b = 100
    }else if (3) {
        var c = 100
    } else {
        var d = 100
    }`
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 1, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "a", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 2, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "b", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 100, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: 'if', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: 3, tokenType: TokenType.number},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "c", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 100, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: 'else', tokenType: TokenType.keyword},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "d", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 100, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},

    ]
    const result = parser(tokenList, 0)

    const expect =  [{
        type:  AstType.StatementIf,
        // if块运行的条件, 可以是表达式等
        condition: {
            type: TokenType.number,
            value: 1
        },
        // if的condition为true时，执行的作用域
        consequent: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable:{
                        type: TokenType.variable,
                        value:"a",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        },
        // else的作用域
        alternate: {
            type: AstType.StatementIf,
            condition: {
                type: TokenType.number,
                value: 2
            },
            consequent: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.DeclarationVariable,
                        kind: 'var',
                        variable: {
                            type: TokenType.variable,
                            value:"b",
                        },
                        value: {
                            type: TokenType.number,
                            value: 100,
                        }
                    },
                ]
            },
            alternate:{
                type: AstType.StatementIf,
                    condition: {
                    type: TokenType.number,
                        value: 3
                },
                consequent: {
                    type: AstType.StatementBlock,
                        body: [
                        {
                            type: AstType.DeclarationVariable,
                            kind: 'var',
                            variable: {
                                type: TokenType.variable,
                                value:"c",
                            },
                            value: {
                                type: TokenType.number,
                                value: 100,
                            }
                        },
                    ]
                },
                 alternate:
                        {
                        type: AstType.StatementBlock,
                        body: [
                            {
                                type: AstType.DeclarationVariable,
                                kind: 'var',
                                variable: {
                                    type: TokenType.variable,
                                    value:"d",
                                },
                                value: {
                                    type: TokenType.number,
                                    value: 100,
                                }
                            },
                        ]
                    }
            }


        }
    }]
    ensure(equals(result, expect), '### test_StatementIf_3')
}
const test_StatementWhile_1 = () => {
    //while
    const code = `while (true) {
        var a = 99
    }`
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'while', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},
        {tokenValue: true, tokenType: TokenType.boolean},
        {tokenValue: ',', tokenType: TokenType.comma},
        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "a", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},
    ]
    const result = parser(tokenList, 0)

    const expect = [{
        type: AstType.StatementWhile,
        condition: {
            type: TokenType.boolean,
            value: true
        },
        // while的condition为true时，执行的作用域
        body: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable:{
                        type: TokenType.variable,
                        value:"a",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        }
    }]
    // log("finally expect", expect)
    ensure(equals(result, expect), '### test_StatementWhile_1')
}

const test_StatementFor_1 = () => {
    //for
    const code = `for(var i = 0; i < 10; i = 1 + i) {
        var a = 99
    }`
    log("code", code)
    // const tokenList = new TokenList(code)

    const tokenList = [
        {tokenValue: 'for', tokenType: TokenType.keyword},
        {tokenValue: '(', tokenType: TokenType.parenthesesLeft},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "i", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 0, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "i", tokenType: TokenType.variable},
        {tokenValue: '<', tokenType: TokenType.lessThan},
        {tokenValue: 10, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "i", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 1, tokenType: TokenType.number},
        {tokenValue: '+', tokenType: TokenType.plus},
        {tokenValue: "i", tokenType: TokenType.variable},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: ')', tokenType: TokenType.parenthesesRight},
        {tokenValue: "{", tokenType: TokenType.curlyLeft},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "var", tokenType: TokenType.keyword},
        {tokenValue: "a", tokenType: TokenType.variable},
        {tokenValue: '=', tokenType: TokenType.assign},
        {tokenValue: 99, tokenType: TokenType.number},
        {tokenValue: ";", tokenType: TokenType.semicolon},

        {tokenValue: "}", tokenType: TokenType.curlyRight},
        {tokenValue: ";", tokenType: TokenType.semicolon},
    ]

    const expect =  [{
        type: AstType.StatementFor,
        // 初始化
        init: {
            type: AstType.DeclarationVariable,
            kind: 'var',
            variable: {
                type: TokenType.variable,
                value:"i",
            },
            value: {
                type: TokenType.number,
                value: 0,
            }

        },
        // for的循环判断
        condition: {
            type: AstType.ExpressionBinary,
            operator: {
                type: TokenType.lessThan,
                value: "<",
            },
            left: {
                type: TokenType.variable,
                value: "i",
            },
            right: {
                type:  TokenType.number,
                value: 10,
            }
        },
        // for的变量更新
        update: {
            type: AstType.ExpressionAssignment,
            left: {
                type: TokenType.variable,
                value: 'i',
            },
            right: {
                type: AstType.ExpressionBinary,
                operator: {
                    type: TokenType.plus,
                    value: "+",
                },
                left: {
                    type: TokenType.number,
                    value: 1,
                },
                right:
                    {
                        type: TokenType.variable,
                        value: 'i',
                    },
            }
        },
        body: {
            type: AstType.StatementBlock,
            body: [
                // 函数体是一条条语句组成的，所以是数组
                {
                    type: AstType.DeclarationVariable,
                    kind: 'var',
                    variable: {
                        type: TokenType.variable,
                        value:"a",
                    },
                    value: {
                        type: TokenType.number,
                        value: 99,
                    }
                },
            ]
        }
    }]
    // log("tokens", tokenList)
    // log("finally expect", expect)
    const result = parser(tokenList, 0)
    ensure(equals(result, expect), '### test_StatementFor_1')
}

